﻿using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Xml;
#if L2S
using System.Data.Linq;
using System.Data.Linq.Mapping;
#endif

namespace ALinq.Mapping
{
    /// <summary>
    /// Represents the mapping between a field or a property of a domain object into a column of a database table.
    /// </summary>
    public class ColumnMapping : ModelMapping
    {
        private MemberInfo member;

        ///<summary>
        ///Initializes a new instance of the ALinq.Mapping.ColumnMapping class
        ///</summary>
        /// <param name="member">The underlying System.Reflection.MemberInfo.</param>
        public ColumnMapping(MemberInfo member)
            : base(ModelMappingType.Column)
        {
            Error.ValidateArgumentNotNull(() => member);
            this.Member = member;
        }

        /// <summary>
        /// Gets the name of the column in the database.
        /// </summary>
        public string Name
        {
            get { return this.GetAttribute(() => Name); }
            set { this.SetAttribute(() => Name, value); }
        }

        /// <summary>
        /// Gets the underlying System.Reflection.MemberInfo.
        /// </summary>
        public MemberInfo Member
        {
            get { return this.member; }
            private set
            {
                if (value == null)
                    throw Error.MemberValueCanNotNull("Member");

                this.member = value;
                this.SetAttribute("Member", value.Name);
            }
        }

        /// <summary>
        /// Gets name of the member that stores the data for this member.
        /// </summary>
        public string Storage
        {
            get { return this.GetAttribute(() => Storage); }
            set { this.SetAttribute(() => Storage, value); }
        }

        /// <summary>
        /// Gets whether the value of this member can be assigned the null value.
        /// </summary>
        public bool CanBeNull
        {
            get { return this.GetAttribute(() => CanBeNull); }
            set { this.SetAttribute(() => CanBeNull, value); }
        }

        /// <summary>
        /// Gets whether this member is part of the type's identity.
        /// </summary>
        public bool IsPrimaryKey
        {
            get { return this.GetAttribute(() => IsPrimaryKey); }
            set { this.SetAttribute(() => IsPrimaryKey, value); }
        }

        /// <summary>
        /// Gets the optimistic concurrency check policy for this member.
        /// </summary>
        public UpdateCheck UpdateCheck
        {
            get { return this.GetAttribute(() => UpdateCheck); }
            set { this.SetAttribute(() => UpdateCheck, value); }
        }

        /// <summary>
        /// Gets whether this member represents the inheritance discriminator.
        /// </summary>
        public bool IsDiscriminator
        {
            get { return this.GetAttribute(() => IsDiscriminator); }
            set { this.SetAttribute(() => IsDiscriminator, value); }
        }

        /// <summary>
        /// Gets the read-back behavior for this member for insert and update operations.
        /// </summary>
        public AutoSync AutoSync
        {
            get { return this.GetAttribute(() => AutoSync); }
            set { this.SetAttribute(() => AutoSync, value); }
        }

        /// <summary>
        /// Gets the type of the corresponding database column.
        /// </summary>
        public string DbType
        {
            get { return this.GetAttribute(() => DbType); }
            set { this.SetAttribute(() => DbType, value); }
        }

        ///<summary>
        /// Gets or sets whether a column contains values that the database auto-generates.
        ///</summary>
        public bool IsDbGenerated
        {
            get { return this.GetAttribute(() => IsDbGenerated); }
            set { this.SetAttribute(() => IsDbGenerated, value); }
        }
    }

}